package com.fowo.api.pda.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.controller.purchase.vo.inventoryTurnoverVo;
import com.fowo.api.entity.*;
import com.fowo.api.inventory.entity.Inventory;
import com.fowo.api.inventory.entity.InventoryPlacement;
import com.fowo.api.inventory.mapper.InventoryMapper;
import com.fowo.api.inventory.model.*;
import com.fowo.api.inventory.model.form.InventoryExchangeFormVo;
import com.fowo.api.inventory.service.InventoryBusinessService;
import com.fowo.api.inventory.service.impl.InventoryPlacementServiceImpl;
import com.fowo.api.mapper.ListingFatherMapper;
import com.fowo.api.model.warehouse.bin.products.WarehouseBinProductsVo;
import com.fowo.api.pda.mapper.PdaInventoryMapper;
import com.fowo.api.pda.model.*;
import com.fowo.api.pda.model.InventoryPlacementItemVo;
import com.fowo.api.pda.service.PdaInventoryService;
import com.fowo.api.service.ShopInfoService;
import com.fowo.api.service.WarehouseBinProductsService;
import com.fowo.api.service.impl.*;
import com.fowo.api.user.model.JwtUserInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PdaInventoryServiceImpl implements PdaInventoryService {
    @Resource
    private ProductServiceImpl productService;
    @Resource
    private ListingFatherServiceImpl listingFatherService;
    @Resource
    private PdaInventoryMapper pdaInventoryMapper;
    @Resource
    private WarehouseBinServiceImpl warehouseBinService;
    @Resource
    private InventoryBusinessService inventoryBusinessService;
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    //主库存表
    @Resource
    private InventoryMapper inventoryMapper;

    @Resource
    private WarehouseBinProductsServiceImpl warehouseBinProductsService;

    @Override
    public List<ProductInventoryVo> getInventoryByProduct(InventoryBo search) throws Exception{
//        Product product = productService.getOne(Wrappers.lambdaQuery(Product.class).eq(Product::getSku,search.getSku()));
//        if(null == product){
//            throw new Exception(search.getSku()+"不存在");
//        }

        List<ProductInventoryVo> productInventoryVos = pdaInventoryMapper.selectShopInventory(search.getStockId(), search.getSku());
        for(ProductInventoryVo vo : productInventoryVos){
//            BeanUtils.copyProperties(product, vo);
            search.setProductId(vo.getId());
            search.setFnSku(vo.getFnsku());
            search.setShopId(vo.getShopId());
            vo.setInventoryList(pdaInventoryMapper.selectInventoryByProduct(search));
        }

        return productInventoryVos;
    }

    @Override
    public WarehouseBinVo getInventoryByBin(Long stockId, String storageBin){
        WarehouseBin warehouseBin = warehouseBinService.getOne(Wrappers.lambdaQuery(WarehouseBin.class)
                .eq(WarehouseBin::getStorageBin,storageBin)
                .eq(WarehouseBin::getWarehouseId,stockId));
        Assert.notNull(warehouseBin,"仓库中没有此仓位");
        WarehouseBinVo model = new WarehouseBinVo();
        BeanUtils.copyProperties(warehouseBin,model);
        final List<InventoryPlacementItemVo> inventoryPlacementItemVos = pdaInventoryMapper.selectInventoryByBin(stockId, warehouseBin.getId());
        Integer inventory = inventoryPlacementItemVos.stream().mapToInt(i -> i.getStockQty().intValue()).sum();
        model.setCount(inventoryPlacementItemVos.size());
        model.setInventory(inventory);
        model.setInventoryList(inventoryPlacementItemVos);
        return model;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void moveBin(PutawayVo model) throws Exception {
        final WarehouseBin one = warehouseBinService.getOne(Wrappers.lambdaQuery(WarehouseBin.class)
                .eq(WarehouseBin::getWarehouseId, model.getWid())
                .eq(WarehouseBin::getStorageBin, model.getBin()));
        if(null == one){
            throw new Exception("移入仓位不存在");
        }
        model.setToBinId(one.getId());
//        InventoryExchangeFormVo formVo = prepareInventoryTurnover(model);
//        inventoryBusinessService.exchange(formVo);

        List<WarehouseBinProducts> binProductsList =  warehouseBinProductsService.list(Wrappers.lambdaQuery(WarehouseBinProducts.class)
                .eq(WarehouseBinProducts::getProductId, model.getProductId())
                .eq(WarehouseBinProducts::getParentId, model.getFromBinId()));

        for(WarehouseBinProducts old : binProductsList){
            // 转移绑定关系
            WarehouseBinProductsVo warehouseBinProducts = new WarehouseBinProductsVo();
            BeanUtils.copyProperties(old,warehouseBinProducts);
            warehouseBinProducts.setParentId(model.getToBinId());
            warehouseBinProductsService.update(warehouseBinProducts);

            InventoryBo bo = new InventoryBo();
            bo.setStockId(model.getWid());
            bo.setProductId(model.getProductId());
            bo.setBinId(model.getFromBinId());
            bo.setShopId(old.getShopId());
            bo.setFnSku(old.getFnskuName());
            List<InventoryPlacement> inventoryPlacementList = pdaInventoryMapper.selectInventoryPlacement(bo);
            if(CollectionUtil.isNotEmpty(inventoryPlacementList)){
                final int quantity = inventoryPlacementList.get(0).getStockQty().intValue();
                if(quantity > 0){
                    // 仓位转移
                    model.setShopId(old.getShopId());
                    model.setFnSku(old.getFnskuName());
                    model.setQuantity(quantity);
                    InventoryExchangeFormVo formVo = prepareInventoryTurnover(model);
                    inventoryBusinessService.exchange(formVo);
                }
            }

        }

        //仓位转移换仓位
//        changeWarehouseBinProducts(model);
    }

    public void changeWarehouseBinProducts(PutawayVo model)throws Exception {

        WarehouseBinProducts old = warehouseBinProductsService.getOne(Wrappers.lambdaQuery(WarehouseBinProducts.class)
                .eq(WarehouseBinProducts::getProductId, model.getProductId())
                .eq(WarehouseBinProducts::getParentId, model.getFromBinId()));

        WarehouseBinProductsVo warehouseBinProducts = new WarehouseBinProductsVo();
        BeanUtils.copyProperties(old,warehouseBinProducts);
        warehouseBinProducts.setParentId(model.getToBinId());
        warehouseBinProductsService.update(warehouseBinProducts);
    }

    protected InventoryExchangeFormVo prepareInventoryTurnover(PutawayVo vo)
            throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();

        InventoryExchangeFormVo formVo = new InventoryExchangeFormVo();
        formVo.setFrom(TargetTypeEnum.Normal);
        formVo.setTo(TargetTypeEnum.Normal);
        formVo.setFormNum(null);
        formVo.setFormOperator(jwtUserInfo.getUserId().toString());
        formVo.setFromStockId(vo.getWid());
        formVo.setToStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        formVo.setDocumentType(vo.getDocumentType());

        SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
        inventoryItem.setId(vo.getProductId());
        InventoryExchangeVo exchangeItem = new InventoryExchangeVo();
        exchangeItem.setItem(inventoryItem);
        exchangeItem.setQty(BigDecimal.valueOf(vo.getQuantity()));
        exchangeItem.setShopId(
                String.valueOf(vo.getShopId()).equals("null")
                        ? null
                        : String.valueOf(vo.getShopId())
        );
        exchangeItem.setFnSku(
                String.valueOf(vo.getFnSku()).equals("null")
                        ? null
                        : String.valueOf(vo.getFnSku())
        );
        Map<Long, Integer> binIds = new HashMap<>();
        binIds.put(
                vo.getFromBinId(),
                Integer.parseInt(
                        String.valueOf(vo.getQuantity()).equals("null")
                                ? "0"
                                : String.valueOf(vo.getQuantity())
                )
        );
        exchangeItem.setFromBinIds(binIds);
        Map<Long, Integer> toBinIds = new HashMap<>();
        toBinIds.put(
                vo.getToBinId(),
                Integer.parseInt(
                        String.valueOf(vo.getQuantity()).equals("null")
                                ? "0"
                                : String.valueOf(vo.getQuantity())
                )
        );
        exchangeItem.setToBinIds(toBinIds);
        exchangeItem.setFromBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setToBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setCustomId(vo.getId());
        exchangeItem.setCustomBdId(null);
        formVo.add(exchangeItem);
        return formVo;
    }

    @Override
    public List<InventoryPlacementItemVo> getInventoryPlacementItemVo(InventoryBo search){
        return pdaInventoryMapper.selectInventoryPlacementItemVo(search);
    }
}
